package net.cyue.homework.student.management.servlet.user;

import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpSession;
import jakarta.validation.Valid;
import net.cyue.homework.student.management.db.DBConnectionPool;
import net.cyue.homework.student.management.dto.UserRegisterDTO;
import net.cyue.homework.student.management.dto.UserUpdatePasswordDTO;
import net.cyue.homework.student.management.http.HTTPServlet;
import net.cyue.homework.student.management.http.annotation.PostMethod;
import net.cyue.homework.student.management.http.annotation.PutMethod;
import net.cyue.homework.student.management.util.CodeUtil;
import net.cyue.homework.student.management.util.DB;
import net.cyue.homework.student.management.util.ResponseUtil;
import net.cyue.nest.nestjava.common.annotation.Body;
import net.cyue.nest.nestjava.common.annotation.Request;
import net.cyue.nest.nestjava.common.annotation.Response;
import net.cyue.nest.nestjava.common.enums.HTTPStatus;
import net.cyue.nest.nestjava.common.interfaces.http.IHTTPRequest;
import net.cyue.nest.nestjava.common.interfaces.http.IHTTPResponse;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.function.Consumer;

@WebServlet(
    name = "UserServlet",
    value = {
        "/action/user",
        "/action/user/"
    }
)
public class UserServlet extends HTTPServlet {

    private void insertUser(UserRegisterDTO user, Consumer<Integer> finished) {
        try {
            DB.POOL.transactionPreparedUpdate(
                "insert into user (username, password, email) values (?, ?, ?)",
                List.of(
                    new DBConnectionPool.Parameter(user.getUsername()),
                    new DBConnectionPool.Parameter(user.getPassword()),
                    new DBConnectionPool.Parameter(user.getEmail())
                ),
                (rows) -> {
                    if (finished != null) {
                        finished.accept(rows);
                    }
                }
            );
        } catch (SQLException e) {
            e.printStackTrace();
            finished.accept(0);
        }
    }


    /**
     * 注册
     * @param request request
     * @param response response
     */
    @PostMethod
    public void addUser(
        @Request IHTTPRequest request,
        @Response IHTTPResponse response,
        @Valid @Body UserRegisterDTO dto
    ) {
        if (
            !CodeUtil.verifyCode(request, dto.getCode())
        ) {
            response.status(HTTPStatus.BAD_REQUEST);
            ResponseUtil.showMessage(response, "验证码错误");
            return;
        }

        try {
            DB.POOL.transactionPreparedQuery(
            "select id from user where username = ?",
                new Object[] {
                    dto.getUsername()
                },
                (resultSet) -> {
                    if (resultSet.next()) {
                        ResponseUtil.showMessage(response, "用户名已存在");
                        return;
                    }
                    this.insertUser(
                        dto,
                        (rows) -> {
                            if (rows == 0) {
                                response.code(HTTPStatus.BAD_REQUEST);
                                ResponseUtil.showMessage(response, "注册失败");
                                return;
                            }
                            ResponseUtil.waitBackHome(response, 2500, "注册成功");
                        }
                    );
                }
            );
        } catch (SQLException e) {
            response.code(HTTPStatus.INTERNAL_SERVER_ERROR);
            ResponseUtil.showMessage(response, "内部错误");
            throw new RuntimeException(e);
        }

    }


    /**
     * 修改密码
     * */
    @PutMethod
    public void UpdatePassword(
        @Request IHTTPRequest request,
        @Response IHTTPResponse response,
        @Valid @Body UserUpdatePasswordDTO dto
    ) {
        if (dto.getPassword().equals(dto.getNewPassword())) {
            ResponseUtil.showMessage(response, "新旧密码相同");
            return;
        }

        HttpSession session = request.getSession();
        int userID = (int) session.getAttribute("userID");
        String userIDString = String.valueOf(userID);
        try {
            String selectSQL = DB.generateSQL(
            "select password from user where id = ?",
                List.of(
                    userIDString
                )
            );
            ResultSet resultSet = DB.POOL.query(selectSQL);
            if (!resultSet.next()) {
                response.code(HTTPStatus.BAD_REQUEST);
                ResponseUtil.showMessage(response, "用户不存在");
                return;
            }
            String originalPassword = resultSet.getString("password");
            if (!originalPassword.equals(dto.getPassword())) {
                ResponseUtil.showMessage(response, "原密码错误");
                return;
            }
            resultSet.close();


            String sql = DB.generateSQL(
                "update user set password = ? where id = ?",
                List.of(
                    dto.getNewPassword(),
                    userIDString
                )
            );
            int rows = DB.POOL.transactionUpdate(sql);
            if (rows == 0) {
                response.code(HTTPStatus.BAD_REQUEST);
                ResponseUtil.showMessage(response, "修改失败");
                return;
            }
            ResponseUtil.showMessage(response, "修改成功");

        } catch (SQLException e) {
            response.code(HTTPStatus.INTERNAL_SERVER_ERROR);
            ResponseUtil.showMessage(response, "内部错误");
            throw new RuntimeException(e);
        }
    }
}


